package commands

import (
	"context"
	"fmt"

	"github.com/spf13/cobra"
	"github.com/yourusername/virt-manager-go/internal/models"
)

// NewStorageCommand 创建存储管理命令
func NewStorageCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "storage",
		Short: "存储管理",
		Long:  "管理存储池和存储卷",
	}

	cmd.AddCommand(newStoragePoolCommand())
	cmd.AddCommand(newStorageVolumeCommand())

	return cmd
}

// NewStoragePoolCommand 创建存储池管理命令
func newStoragePoolCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "pool",
		Short: "存储池管理",
		Long:  "管理存储池",
	}

	cmd.AddCommand(newStoragePoolListCommand())
	cmd.AddCommand(newStoragePoolGetCommand())
	cmd.AddCommand(newStoragePoolCreateCommand())
	cmd.AddCommand(newStoragePoolDeleteCommand())
	cmd.AddCommand(newStoragePoolStartCommand())
	cmd.AddCommand(newStoragePoolStopCommand())
	cmd.AddCommand(newStoragePoolXMLCommand())

	return cmd
}

func newStoragePoolListCommand() *cobra.Command {
	var (
		outputFormat string
		connectionID string
	)

	cmd := &cobra.Command{
		Use:   "list",
		Short: "列出所有存储池",
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			pools, err := client.Storage().ListStoragePools(context.Background(), connectionID)
			if err != nil {
				return fmt.Errorf("列出存储池失败: %w", err)
			}

			return printOutput(pools, outputFormat)
		},
	}

	cmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "输出格式 (table, json, yaml)")
	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStoragePoolGetCommand() *cobra.Command {
	var (
		outputFormat string
		connectionID string
	)

	cmd := &cobra.Command{
		Use:   "get [name]",
		Short: "获取存储池详情",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			pool, err := client.Storage().GetStoragePool(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("获取存储池详情失败: %w", err)
			}

			return printOutput(pool, outputFormat)
		},
	}

	cmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "输出格式 (table, json, yaml)")
	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStoragePoolCreateCommand() *cobra.Command {
	var (
		connectionID string
		xmlConfig    string
	)

	cmd := &cobra.Command{
		Use:   "create [name]",
		Short: "创建新存储池",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())

			err := client.Storage().CreateStoragePool(context.Background(), connectionID, xmlConfig)
			if err != nil {
				return fmt.Errorf("创建存储池失败: %w", err)
			}

			fmt.Printf("✅ 存储池 %s 创建成功\n", args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	cmd.Flags().StringVar(&xmlConfig, "xml", "", "存储池 XML 配置")
	return cmd
}

func newStoragePoolDeleteCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "delete [name]",
		Short: "删除存储池",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			err := client.Storage().DeleteStoragePool(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("删除存储池失败: %w", err)
			}

			fmt.Printf("✅ 存储池 %s 删除成功\n", args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStoragePoolStartCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "start [name]",
		Short: "启动存储池",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			err := client.Storage().StartStoragePool(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("启动存储池失败: %w", err)
			}

			fmt.Printf("✅ 存储池 %s 启动成功\n", args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStoragePoolStopCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "stop [name]",
		Short: "停止存储池",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			err := client.Storage().StopStoragePool(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("停止存储池失败: %w", err)
			}

			fmt.Printf("✅ 存储池 %s 停止成功\n", args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStoragePoolXMLCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "xml [name]",
		Short: "获取存储池 XML 配置",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			xml, err := client.Storage().GetStoragePoolXML(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("获取存储池 XML 配置失败: %w", err)
			}

			fmt.Println(xml)
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

// NewStorageVolumeCommand 创建存储卷管理命令
func newStorageVolumeCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "volume",
		Short: "存储卷管理",
		Long:  "管理存储卷",
	}

	cmd.AddCommand(newStorageVolumeListCommand())
	cmd.AddCommand(newStorageVolumeGetCommand())
	cmd.AddCommand(newStorageVolumeCreateCommand())
	cmd.AddCommand(newStorageVolumeDeleteCommand())
	cmd.AddCommand(newStorageVolumeXMLCommand())

	return cmd
}

func newStorageVolumeListCommand() *cobra.Command {
	var (
		outputFormat string
		connectionID string
	)

	cmd := &cobra.Command{
		Use:   "list [pool]",
		Short: "列出存储池中的所有卷",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			volumes, err := client.Storage().ListStorageVolumes(context.Background(), connectionID, args[0])
			if err != nil {
				return fmt.Errorf("列出存储卷失败: %w", err)
			}

			return printOutput(volumes, outputFormat)
		},
	}

	cmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "输出格式 (table, json, yaml)")
	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStorageVolumeGetCommand() *cobra.Command {
	var (
		outputFormat string
		connectionID string
	)

	cmd := &cobra.Command{
		Use:   "get [pool] [volume]",
		Short: "获取存储卷详情",
		Args:  cobra.ExactArgs(2),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			volume, err := client.Storage().GetStorageVolume(context.Background(), connectionID, args[0], args[1])
			if err != nil {
				return fmt.Errorf("获取存储卷详情失败: %w", err)
			}

			return printOutput(volume, outputFormat)
		},
	}

	cmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "输出格式 (table, json, yaml)")
	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStorageVolumeCreateCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "create [pool] [volume]",
		Short: "创建新存储卷",
		Args:  cobra.ExactArgs(2),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			req := &models.CreateVolumeRequest{
				Name: args[1],
			}

			err := client.Storage().CreateStorageVolume(context.Background(), connectionID, args[0], req)
			if err != nil {
				return fmt.Errorf("创建存储卷失败: %w", err)
			}

			fmt.Printf("✅ 存储卷 %s 在存储池 %s 中创建成功\n", args[1], args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStorageVolumeDeleteCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "delete [pool] [volume]",
		Short: "删除存储卷",
		Args:  cobra.ExactArgs(2),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			err := client.Storage().DeleteStorageVolume(context.Background(), connectionID, args[0], args[1])
			if err != nil {
				return fmt.Errorf("删除存储卷失败: %w", err)
			}

			fmt.Printf("✅ 存储卷 %s 从存储池 %s 中删除成功\n", args[1], args[0])
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}

func newStorageVolumeXMLCommand() *cobra.Command {
	var connectionID string

	cmd := &cobra.Command{
		Use:   "xml [pool] [volume]",
		Short: "获取存储卷 XML 配置",
		Args:  cobra.ExactArgs(2),
		RunE: func(cmd *cobra.Command, args []string) error {
			client := ClientManager.GetClient(cmd.Flag("server").Value.String())
			xml, err := client.Storage().GetStorageVolumeXML(context.Background(), connectionID, args[0], args[1])
			if err != nil {
				return fmt.Errorf("获取存储卷 XML 配置失败: %w", err)
			}

			fmt.Println(xml)
			return nil
		},
	}

	cmd.Flags().StringVarP(&connectionID, "connection", "c", "", "连接 ID")
	return cmd
}
